<template>
  <div class="img-file-upLoad">
    <template v-if="browserVersion >= 71 && browserVersion <= 74">
      <a-upload
        v-model:file-list="antdFileList"
        list-type="picture-card"
        class="ant-avatar-uploader"
        :headers="header"
        :action="uploadUrl"
        :maxCount="maxCount"
        :accept="fileAccept"
        @change="handleChange"
      >
        <div v-if="antdFileList.length < 8">
          <loading-outlined v-if="loading"></loading-outlined>
          <plus-outlined />
          <div style="margin-top: 8px">Upload</div>
        </div>
      </a-upload>
    </template>
    <template v-else>
      <!-- 'single-img': hideUpload, -->
      <el-upload
        class="avatar-uploader max"
        ref="uploadRef"
        :headers="header"
        :action="uploadUrl"
        :show-file-list="true"
        :on-success="handleAvatarSuccess"
        :limit="maxCount"
        :on-preview="handlePictureCardPreview"
        :file-list="defaultList"
        :class="{ 'single-img': hideUpload, min: size === 'min' }"
        list-type="picture-card"
        :disabled="disabled"
        :before-upload="beforeUpload"
        :on-exceed="onExceed"
        :on-error="uploadError"
        :accept="fileAccept"
      >
        <el-icon size="36">
          <Plus />
        </el-icon>
        <template #file="{ file }">
          <template v-if="['finished', 'success'].indexOf(file.status) != -1">
            <svg-icon
              style="width: 100%; height: 100%; padding: 20px"
              v-if="getExtByName(file)"
              icon-class="pdf"
            />
            <img style="width: 100%" v-else :src="file.url" />
          </template>
          <template v-else>
            <el-progress
              type="circle"
              :width="45"
              style="width: 45px"
              :percentage="file.percentage"
              :show-text="false"
            ></el-progress>
          </template>

          <span class="el-upload-list__item-actions">
            <span
              class="el-upload-list__item-delete"
              @click="handlePictureCardPreview(file)"
            >
              <!--              <i class="el-icon-zoom-in"></i>-->
              <el-icon size="36">
                <ZoomIn />
              </el-icon>
            </span>
            <span
              v-if="!disabled"
              class="el-upload-list__item-delete"
              @click="handleRemove(file, fileList)"
            >
              <el-icon size="36">
                <Delete />
              </el-icon>
              <!--              <i class="el-icon-delete"></i>-->
            </span>
          </span>
        </template>
      </el-upload>
    </template>

    <el-image-viewer
      @close="closeImgViewer"
      :url-list="imageList"
      :initial-index="previewIndex"
      v-if="imageList.length > 0"
    ></el-image-viewer>
    <el-dialog v-model="dialogVisiblePdf">
      <PDF :src="pdfUrl"></PDF>
    </el-dialog>
  </div>
</template>
<script>
  import { computed, ref } from '@vue/runtime-core'
  import { watch } from 'vue'
  import { useStore } from 'vuex'
  import { isString } from '@/utils/validate'
  import { Plus, ZoomIn, Delete } from '@element-plus/icons-vue'
  import PDF from '@/components/PDF'
  import aUpload from 'ant-design-vue/lib/upload' // 加载 JS
  import 'ant-design-vue/lib/upload/style/css'
  import { PlusOutlined } from '@ant-design/icons-vue'
  import common from '@/utils/common.js'
  import SvgIcon from '@/components/SvgIcon/index.vue'
  import { uploadNetTools, useUpload } from '@/hooks/elementUI/useUpload'
  export default {
    name: 'ImgFileUpLoad',
    components: { SvgIcon, Plus, aUpload, PlusOutlined, PDF, Delete, ZoomIn },
    // size:控制大小 min , type: 控制是单选还是多选 single multi
    props: {
      modelValue: String,
      disabled: Boolean,
      size: {
        type: String,
        default() {
          // size:控制大小 min max
          return 'max'
        },
      },
      type: {
        type: String,
        default() {
          // type: 控制是单选还是多选 single multi
          return 'single'
        },
      },
      maxCount: {
        type: Number,
        default() {
          return 9
        },
      },
      maxFileSize: {
        type: Number,
        default() {
          return 10
        },
      },
      fileAccept: {
        type: String,
        default() {
          return '.png,.jpg,.jpeg,.gif'
        },
      },
    },
    emits: ['success', 'update:modelValue'],
    setup(props, context) {
      const imageList = ref([])
      const store = useStore()
      // 存放对象
      const listObj = ref({})
      const defaultList = ref([])

      const hideUpload = computed(() => {
        return (
          defaultList.value.length + Object.keys(listObj.value).length >=
          props.maxCount
        )
      })

      const { checkAllSuccess, removeFile, uploadSuccess, uploadBefore } =
        useUpload(listObj)
      const { header, uploadUrl } = uploadNetTools()

      watch(
        () => props.modelValue,
        (val) => {
          if (Array.isArray(props.modelValue)) {
            defaultList.value = props.modelValue
            return
          } else if (isString(props.modelValue)) {
            // string 新旧系统转换
            try {
              defaultList.value = JSON.parse(props.modelValue)
              return
            } catch (err) {
              if (props.modelValue.length > 0) {
                defaultList.value = [{ url: props.modelValue }]
                return
              }
              defaultList.value = []
              return
            }
            // return props.modelValue ? JSON.parse(props.modelValue) : []
          }
          defaultList.value = props.modelValue
            ? [{ url: props.modelValue }]
            : []
        },
        { immediate: true, deep: true }
      )
      const getStatus = function () {
        if (browserVersion.value <= 74 && browserVersion.value >= 71) {
          const list = defaultList.value.filter(
            (item) => item.status === 'uploading'
          )
          if (list.length > 0) {
            return false
          } else {
            const list = Object.keys(defaultList.value).map((v) => {
              const item = defaultList.value[v]
              return {
                name: item.name,
                uid: item.uid,
                url: item.url,
              }
            })
            context.emit('update:modelValue', JSON.stringify(list))
            return true
          }
        }
        if (!checkAllSuccess()) {
          return false
        }
        const list = Object.keys(listObj.value).map((v) => {
          const item = listObj.value[v]
          return {
            name: common.getUrlName(item.url),
            uid: item.uid,
            url: item.url,
          }
        })

        const allFile = defaultList.value.concat(list)

        context.emit('update:modelValue', JSON.stringify(allFile))

        listObj.value = {}
        return true
      }
      // 放给外部调用
      // defineExpose({ getStatus })

      // 控制预览
      const dialogVisiblePdf = ref()
      const pdfUrl = ref()
      const previewIndex = ref()
      const handlePictureCardPreview = function (file) {
        let tmpUrl = file.url
        const { response } = file
        if (response && response.data) tmpUrl = response.data
        if (
          common.getExtByName(file.url) === 'pdf' ||
          common.getExtByName(file.name) === 'pdf'
        ) {
          dialogVisiblePdf.value = true
          pdfUrl.value = tmpUrl
        } else {
          const list = Object.keys(listObj.value).map((v) => {
            const item = listObj.value[v]
            return {
              name: common.getUrlName(item.url),
              uid: item.uid,
              url: item.url,
            }
          })

          const allFile = defaultList.value.concat(list)
          imageList.value = allFile
            .filter((item) => common.getExtByName(item.url) !== 'pdf')
            .map((item, index) => {
              if (item.url === tmpUrl) previewIndex.value = index
              return item.url
            })
        }

        // imageList.value = fileList.value.map((item) => item.url)
      }
      const closeImgViewer = function () {
        imageList.value = []
      }
      const uploadError = function (error, file, uploadFiles) {
        // 兼容没有权限和断网
        if (error && !file) {
          common.XmMessage(1, error.response.message)
          deleteFunc(error)
        } else {
          common.XmMessage(
            1,
            `文件${file.name}上传失败，请减少体积或检查网络后重试`
          )
          deleteFunc(file)
        }
      }
      const handleAvatarSuccess = function (response, file, files) {
        // 设版本限制
        if (response.code === '0000') {
          uploadSuccess(response, file)
        } else {
          uploadError(file)
        }
      }
      function deleteFunc(file) {
        const list = defaultList.value.filter((item) => item.uid !== file.uid)
        if (list.length < defaultList.value.length) {
          defaultList.value = list
          return
        }
        if (uploadRef.value) uploadRef.value.handleRemove(file)
        removeFile(file)
      }
      const browserVersion = store.getters.browserVersion
      const imageUrl = ref(null)
      const antdFileList = ref([])
      const handleChange = function (params) {
        const { file, fileList } = params
        if (browserVersion <= 74 && browserVersion >= 71) {
          if (
            file.status === 'done' ||
            file.status === 'success' ||
            file.status === 'removed'
          ) {
            const file = fileList
              .filter((item) => item.status === 'success' || item.url)
              .map((item) => {
                return {
                  name: item.name,
                  url: (item.response && item.response.data) || item.url,
                }
              })
            const doFile = fileList
              .filter((item) => item.status === 'done')
              .map((item) => {
                return { name: item.name, url: item.response.data }
              })
            context.emit(
              'update:modelValue',
              JSON.stringify(file.concat(doFile))
            )
          }
        }
      }
      const uploadRef = ref()
      const handleRemove = function (file) {
        // const tmp = fileList.value.filter((item) => item.url !== file.url)
        // context.emit('update:modelValue', JSON.stringify(tmp))
        deleteFunc(file)
      }

      watch(
        () => defaultList.value,
        (val) => {
          if (val.length > 0 && browserVersion <= 74 && browserVersion >= 71) {
            antdFileList.value = val
          }
        },
        { deep: true, immediate: true }
      )
      const beforeUpload = function (file) {
        if (props.maxFileSize && file.size > props.maxFileSize * 1024 * 1024) {
          common.XmMessage(1, `上传失败，文件大小不能大于${props.maxFileSize}M`)
          return false
        }
        return uploadBefore(file)
      }
      const onExceed = function () {
        common.XmMessage(1, `上传失败，已上传最大值 ${props.max}`)
      }

      const getExtByNameImg = computed(() => (file) => {
        const b =
          common.getExtByName(file.url) === 'pdf' ||
          common.getExtByName(file.name) === 'pdf'
        return b
      })
      return {
        onExceed,
        header,
        uploadUrl,
        handleAvatarSuccess,
        defaultList,
        handlePictureCardPreview,
        handleRemove,
        hideUpload,
        handleChange,
        imageList,
        closeImgViewer,
        browserVersion,
        imageUrl,
        antdFileList,
        dialogVisiblePdf,
        pdfUrl,
        getExtByName: getExtByNameImg,
        beforeUpload,
        getStatus,
        uploadError,
        uploadRef,
        previewIndex,
      }
    },
  }
</script>
<style lang="scss">
  .img-file-upLoad {
    .avatar-uploader {
      &.single-img .el-upload--picture-card {
        display: none;
      }

      // 去掉动画
      .el-upload-list__item {
        transition: none !important;
      }

      .el-upload-list__item-status-label {
        width: 0px !important;
      }
    }

    .max {
      height: 140px;

      .el-upload--picture-card {
        width: 140px;
        height: 140px;
      }

      .el-upload {
        width: 140px;
        height: 140px;
        line-height: 140px;
      }

      .el-upload-list--picture-card .el-upload-list__item {
        width: 140px;
        height: 140px;
        line-height: 140px;
      }

      .el-upload-list--picture-card .el-upload-list__item-thumbnail {
        width: 140px;
        height: 140px;
        line-height: 140px;
      }

      .avatar {
        width: 140px;
        height: 140px;
      }
    }

    .min {
      height: 100px;

      .el-upload--picture-card {
        width: 100px;
        height: 100px;
      }

      .el-upload {
        width: 100px;
        height: 100px;
        line-height: 100px;
      }

      .el-upload-list--picture-card .el-upload-list__item {
        width: 100px;
        height: 100px;
        line-height: 100px;
      }

      .el-upload-list--picture-card .el-upload-list__item-thumbnail {
        width: 100px;
        height: 100px;
        line-height: 100px;
      }

      .avatar {
        width: 100px;
        height: 100px;
      }
    }
  }
</style>
<style>
  .ant-avatar-uploader > .ant-upload {
    width: 128px;
    height: 128px;
  }

  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }
</style>
